<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        function Fee() {
            // . . .
        }

        function Fi() {
            // . . .
        }
        Fi.prototype = new Fee();

        function Fo() {
            // . . .
        }
        Fo.prototype = new Fi();

        function Fum() {
            // . . .
        }
        Fum.prototype = new Fo();
        // 下面创建一个 Fum 实例， 检测 Fi.prototype 是否存在于该实例的原型链上。

        var fum = new Fum();

        //【1】A.isPrototypeOf(B) 判断的是A对象是否存在于B对象的原型链之中
        //语法：   prototypeObj.isPrototypeOf(object)
        //参数：   object  在该对象的原型链上搜寻
        //返回值： Boolean，表示调用对象是否在另一个对象的原型链上。
        //描述：   isPrototypeOf 方法允许你检查一个对象是否存在于另一个对象的原型链上。

        var res = Fi.prototype.isPrototypeOf(fum);
        console.log(res); //true
        //【2】A instanceof B  判断的是B.prototype是否存在与A的原型链之中
        // 语法: object instanceof constructor
        // 参数: object 要检测的对象. constructor 某个构造函数
        // 描述:instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
        // 定义构造函数
        function C() {}

        function D() {}

        var o = new C();

        // true，因为 Object.getPrototypeOf(o) === C.prototype
        o instanceof C;

        // false，因为 D.prototype不在o的原型链上
        o instanceof D;

        o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
        C.prototype instanceof Object // true,同上

        C.prototype = {};
        var o2 = new C();

        o2 instanceof C; // true

        o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

        D.prototype = new C(); // 继承
        var o3 = new D();
        o3 instanceof D; // true
        o3 instanceof C; // true
        // 需要注意的是， 如果表达式 obj instanceof Foo 返回true， 则并不意味着该表达式会永远返回true， 因为Foo.prototype属性的值有可能会改变， 改变之后的值很有可能不存在于obj的原型链上， 这时原表达式的值就会成为false。
        // 另外一种情况下， 原表达式的值也会改变， 就是改变对象obj的原型链的情况， 虽然在目前的ES规范中， 我们只能读取对象的原型而不能改变它， 但借助于非标准的__proto__魔法属性， 是可以实现的。 比如执行obj.__proto__ = {}
        // 之后， obj instanceof Foo就会返回false了。
    </script>
</body>

</html>